*/ public function register(): array { return TokenHelper::ARRAY_TOKEN_CODES; } /** * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint * @param int $stackPointer */ public function process(File $phpcsFile, $stackPointer): int { $this->spacesAroundBrackets = SniffSettingsHelper::normalizeInteger($this->spacesAroundBrackets); $tokens = $phpcsFile->getTokens(); [$arrayOpenerPointer, $arrayCloserPointer] = ArrayHelper::openClosePointers($tokens[$stackPointer]); // Check only single-line arrays. if ($tokens[$arrayOpenerPointer]['line'] !== $tokens[$arrayCloserPointer]['line']) { return $arrayCloserPointer; } $pointerContent = TokenHelper::findNextNonWhitespace($phpcsFile, $arrayOpenerPointer + 1, $arrayCloserPointer + 1); if ($pointerContent === $arrayCloserPointer) { // Empty array, but if the brackets aren't together, there's a problem. if ($this->enableEmptyArrayCheck) { $this->checkWhitespaceInEmptyArray($phpcsFile, $arrayOpenerPointer, $arrayCloserPointer); } // We can return here because there is nothing else to check. // All code below can assume that the array is not empty. return $arrayCloserPointer + 1; } $this->checkWhitespaceAfterOpeningBracket($phpcsFile, $arrayOpenerPointer); $this->checkWhitespaceBeforeClosingBracket($phpcsFile, $arrayCloserPointer); for ($i = $arrayOpenerPointer + 1; $i < $arrayCloserPointer; $i++) { // Skip bracketed statements, like function calls. if ($tokens[$i]['code'] === T_OPEN_PARENTHESIS) { $i = $tokens[$i]['parenthesis_closer']; continue; } // Skip nested arrays as they will be processed separately if (in_array($tokens[$i]['code'], TokenHelper::ARRAY_TOKEN_CODES, true)) { $i = ArrayHelper::openClosePointers($tokens[$i])[1]; continue; } if ($tokens[$i]['code'] !== T_COMMA) { continue; } // Before checking this comma, make sure we are not at the end of the array. $next = TokenHelper::findNextNonWhitespace($phpcsFile, $i + 1, $arrayCloserPointer); if ($next === null) { return $arrayOpenerPointer + 1; } $this->checkWhitespaceBeforeComma($phpcsFile, $i); $this->checkWhitespaceAfterComma($phpcsFile, $i); } return $arrayOpenerPointer + 1; } private function checkWhitespaceInEmptyArray(File $phpcsFile, int $arrayStart, int $arrayEnd): void { if ($arrayEnd - $arrayStart === 1) { return; } $error = 'Empty array declaration must have no space between the parentheses.'; $fix = $phpcsFile->addFixableError($error, $arrayStart, self::CODE_SPACE_IN_EMPTY_ARRAY); if (!$fix) { return; } FixerHelper::replace($phpcsFile, $arrayStart + 1, ''); } private function checkWhitespaceAfterOpeningBracket(File $phpcsFile, int $arrayStart): void { $tokens = $phpcsFile->getTokens(); $whitespacePointer = $arrayStart + 1; $spaceLength = 0; if ($tokens[$whitespacePointer]['code'] === T_WHITESPACE) { $spaceLength = $tokens[$whitespacePointer]['length']; } if ($spaceLength === $this->spacesAroundBrackets) { return; } $error = sprintf('Expected %d spaces after array opening bracket, %d found.', $this->spacesAroundBrackets, $spaceLength); $fix = $phpcsFile->addFixableError($error, $arrayStart, self::CODE_SPACE_AFTER_ARRAY_OPEN); if (!$fix) { return; } if ($spaceLength === 0) { FixerHelper::add($phpcsFile, $arrayStart, str_repeat(' ', $this->spacesAroundBrackets)); } else { FixerHelper::replace( $phpcsFile, $whitespacePointer, str_repeat(' ', $this->spacesAroundBrackets), ); } } private function checkWhitespaceBeforeClosingBracket(File $phpcsFile, int $arrayEnd): void { $tokens = $phpcsFile->getTokens(); $whitespacePointer = $arrayEnd - 1; $spaceLength = 0; if ($tokens[$whitespacePointer]['code'] === T_WHITESPACE) { $spaceLength = $tokens[$whitespacePointer]['length']; } if ($spaceLength === $this->spacesAroundBrackets) { return; } $error = sprintf('Expected %d spaces before array closing bracket, %d found.', $this->spacesAroundBrackets, $spaceLength); $fix = $phpcsFile->addFixableError($error, $arrayEnd, self::CODE_SPACE_BEFORE_ARRAY_CLOSE); if (!$fix) { return; } if ($spaceLength === 0) { FixerHelper::addBefore($phpcsFile, $arrayEnd, str_repeat(' ', $this->spacesAroundBrackets)); } else { FixerHelper::replace( $phpcsFile, $whitespacePointer, str_repeat(' ', $this->spacesAroundBrackets), ); } } private function checkWhitespaceBeforeComma(File $phpcsFile, int $comma): void { $tokens = $phpcsFile->getTokens(); if ($tokens[$comma - 1]['code'] !== T_WHITESPACE) { return; } if ($tokens[$comma - 2]['code'] === T_COMMA) { return; } $error = sprintf( 'Expected 0 spaces between "%s" and comma, %d found.', $tokens[$comma - 2]['content'], $tokens[$comma - 1]['length'], ); $fix = $phpcsFile->addFixableError($error, $comma, self::CODE_SPACE_BEFORE_COMMA); if (!$fix) { return; } FixerHelper::replace($phpcsFile, $comma - 1, ''); } private function checkWhitespaceAfterComma(File $phpcsFile, int $comma): void { $tokens = $phpcsFile->getTokens(); if ($tokens[$comma + 1]['code'] !== T_WHITESPACE) { $error = sprintf('Expected 1 space between comma and "%s", 0 found.', $tokens[$comma + 1]['content']); $fix = $phpcsFile->addFixableError($error, $comma, self::CODE_SPACE_AFTER_COMMA); if ($fix) { FixerHelper::add($phpcsFile, $comma, ' '); } return; } $spaceLength = $tokens[$comma + 1]['length']; if ($spaceLength === 1) { return; } $error = sprintf('Expected 1 space between comma and "%s", %d found.', $tokens[$comma + 2]['content'], $spaceLength); $fix = $phpcsFile->addFixableError($error, $comma, self::CODE_SPACE_AFTER_COMMA); if (!$fix) { return; } FixerHelper::replace($phpcsFile, $comma + 1, ' '); } }